package com.chenssy.register.core;

import com.chenssy.common.core.InstanceInfo;
import com.chenssy.common.core.Lease;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

/**
 * 服务状态检查监控器
 * @author:chenssy
 * @date:2021/6/30
 */
@Slf4j
public class ServiceStatusMonitor {

    private Long aliveduration = 5 * 1000L;

    private Timer serviceAliveMonitorTimer;

    public ServiceStatusMonitor() {
        serviceAliveMonitorTimer = new Timer("ServiceAliveMonitor");
    }

    /**
     * 监控器启动
     */
    public void start() {
        serviceAliveMonitorTimer.schedule(new ServiceAliveMonitor(),new Date(),aliveduration);
    }

    /**
     * 服务是否还存活
     */
    private class ServiceAliveMonitor extends TimerTask {

        @SneakyThrows
        @Override
        public  void run() {

            log.info("[ServiceAliveMonitor] - 执行...");

            SelfProtector selfProtector = SelfProtector.getInstance();
            if (selfProtector.isSelfProtection()) {
                log.info("register-server 进入自我保护机制....");
                Thread.sleep(30 * 1000);
                return;
            }

            Map<String, Map<String,Lease<InstanceInfo>>> register = InstanceRegister.getInstance().getAllRegistry();

            if (register == null || register.isEmpty()) {
                log.info("[ServiceAliveMonitor] - 注册表 register 为空..");
                return;
            }

            for (Map.Entry<String,Map<String, Lease<InstanceInfo>>> registerEntiry : register.entrySet()) {

               for (Map.Entry<String,Lease<InstanceInfo>> leaseEntry : registerEntiry.getValue().entrySet()) {

                   Lease lease = leaseEntry.getValue();
                   Long lastUpdateTimestamp = lease.getLastUpdateTimestamp();
                   if (lastUpdateTimestamp < System.currentTimeMillis()) {
                       log.info("[ServiceAliveMonitor] - 服务[{}-{}]已超过过期时间，进行摘除..",registerEntiry.getKey(),leaseEntry.getKey());

                       // 摘除实例
                       registerEntiry.getValue().remove(leaseEntry.getKey());

                       // 如果服务中的实例没有了，就摘除该服务
                       if (registerEntiry.getValue().size() < 1) {
                           register.remove(registerEntiry.getKey());
                       }
                   } else {
                       log.info("[ServiceAliveMonitor] - 校验[{} - {}]存活..",registerEntiry.getKey(),leaseEntry.getKey());
                   }
               }
            }
        }
    }
}
